import 'package:mobx/mobx.dart';
import 'package:thal/backstage/blueprint/quiz_print.dart';

part 'quiz_room.g.dart';

/// 答题状态管理
class QuizRoom = _QuizRoom with _$QuizRoom;

abstract class _QuizRoom with Store {
  /// 题目列表
  @observable
  ObservableList<QuizQuestionPrint> questions =
      ObservableList<QuizQuestionPrint>();

  /// 用户答题记录列表
  @observable
  ObservableList<QuizAttemptPrint> quizAttempts =
      ObservableList<QuizAttemptPrint>();

  /// 初始化默认题目数据
  @action
  void initializeDefaultQuizQuestions() {
    questions = ObservableList<QuizQuestionPrint>.of([
      QuizQuestionPrint(
        id: '1',
        question:
            'Which of the following is a unique feature of the Great Blue Heron when foraging?',
        options: [
          'The world’s largest freshwater lake by surface area',
          'The world’s deepest and largest freshwater lake by volume',
          'The world’s highest-altitude freshwater lake',
          'The world’s coldest freshwater lake by water temperature',
        ],
        correctAnswerIndex: 1, // Lake Baikal
      ),
      QuizQuestionPrint(
        id: '2',
        question:
            'The formation of Crater Lake in the United States is directly related to which geological activity?',
        options: [
          'Glacial erosion',
          'Volcanic eruption followed by caldera collapse',
          'Fault depression caused by tectonic plate collision',
          'River diversion and sediment accumulation',
        ],
        correctAnswerIndex: 1, // Volcanic crater lake
      ),
      QuizQuestionPrint(
        id: '3',
        question:
            'Why does Emerald Lake in Canada’s Yoho National Park exhibit a unique emerald-green color?',
        options: [
          'Abundant emerald ore fragments in the lake',
          'Light scattering by glacial flour carried in meltwater',
          'Special algae growing on the lake bottom',
          'Green light reflection from surrounding forests',
        ],
        correctAnswerIndex: 1, // Jade Lake
      ),
      QuizQuestionPrint(
        id: '4',
        question:
            'Which lake is the only one in the world inhabited by freshwater seals?',
        options: [
          'Lake Superior (one of the Great Lakes of North America)',
          'Lake Baikal (Russia)',
          'Lake Como (Italy)',
          'Lake Matheson (New Zealand)',
        ],
        correctAnswerIndex: 1,
      ),
      QuizQuestionPrint(
        id: '5',
        question:
            'Crater Lake is the deepest lake in the United States. What is its main source of water supply?',
        options: [
          'Inflow from surrounding rivers',
          'Groundwater seepage',
          'Rainfall and snowmelt',
          'Direct glacial ablation',
        ],
        correctAnswerIndex: 2,
      ),
      QuizQuestionPrint(
        id: '6',
        question:
            'Lake Como in Italy, famous for its narrow shape and lakeside castles, belongs to which type of lake?',
        options: [
          'Crater lake',
          'Glacial lake',
          'Tectonic lake (fault lake)',
          'Artificial lake (reservoir)',
        ],
        correctAnswerIndex: 1, // Crater Lake
      ),
    ]);
  }

  /// 获取所有题目
  List<QuizQuestionPrint> fetchAllQuestions() {
    return List.from(questions);
  }

  /// 根据ID获取题目
  QuizQuestionPrint? fetchQuestionById(String id) {
    try {
      return questions.firstWhere((question) => question.id == id);
    } catch (e) {
      return null;
    }
  }

  /// 获取用户的所有答题记录
  List<QuizAttemptPrint> fetchUserQuizAttempts(String userId) {
    return quizAttempts.where((attempt) => attempt.userId == userId).toList()
      ..sort((a, b) => b.attemptDate.compareTo(a.attemptDate)); // 按时间倒序
  }

  /// 获取用户本月的答题记录
  List<QuizAttemptPrint> fetchUserMonthlyQuizAttempts(String userId) {
    final now = DateTime.now();
    final startOfMonth = DateTime(now.year, now.month, 1);

    return quizAttempts
        .where(
          (attempt) =>
              attempt.userId == userId &&
              attempt.attemptDate.isAfter(startOfMonth),
        )
        .toList()
      ..sort((a, b) => b.attemptDate.compareTo(a.attemptDate));
  }

  /// 检查用户本月是否已获得徽章
  bool hasUserEarnedBadgeThisMonth(String userId) {
    final monthlyAttempts = fetchUserMonthlyQuizAttempts(userId);
    return monthlyAttempts.any((attempt) => attempt.awardedBadgeId != null);
  }

  /// 开始答题 - 检查用户本月是否还能获得徽章
  bool canUserStartQuiz(String userId) {
    return !hasUserEarnedBadgeThisMonth(userId);
  }

  /// 提交答题结果
  @action
  QuizAttemptPrint submitQuizAnswers({
    required String userId,
    required List<int> userAnswers,
  }) {
    // 验证答案数量
    if (userAnswers.length != questions.length) {
      throw Exception('Answer count does not match question count');
    }

    // 计算答对题目数量
    int correctCount = 0;
    for (int i = 0; i < questions.length; i++) {
      if (userAnswers[i] == questions[i].correctAnswerIndex) {
        correctCount++;
      }
    }

    // 判断是否通过 (答对3题以上)
    bool passed = correctCount >= 3;

    // 创建答题记录
    final attempt = QuizAttemptPrint(
      id: '${DateTime.now().millisecondsSinceEpoch}',
      userId: userId,
      attemptDate: DateTime.now(),
      userAnswers: List.from(userAnswers),
      correctCount: correctCount,
      passed: passed,
      awardedBadgeId: null, // 暂时不设置徽章ID
    );

    // 添加到记录列表
    quizAttempts.add(attempt);

    return attempt;
  }

  /// 为用户分配徽章 (如果通过且本月未获得)
  @action
  String? awardBadgeToUser(String userId, String badgeId) {
    // 检查用户本月是否已获得徽章
    if (hasUserEarnedBadgeThisMonth(userId)) {
      return null; // 本月已获得徽章
    }

    // 获取用户最新的答题记录
    final userAttempts = fetchUserQuizAttempts(userId);
    if (userAttempts.isEmpty) {
      return null; // 没有答题记录
    }

    final latestAttempt = userAttempts.first;
    if (!latestAttempt.passed) {
      return null; // 未通过答题
    }

    // 更新最新的答题记录，添加徽章ID
    final updatedAttempt = QuizAttemptPrint(
      id: latestAttempt.id,
      userId: latestAttempt.userId,
      attemptDate: latestAttempt.attemptDate,
      userAnswers: latestAttempt.userAnswers,
      correctCount: latestAttempt.correctCount,
      passed: latestAttempt.passed,
      awardedBadgeId: badgeId,
    );

    // 替换记录
    final index = quizAttempts.indexWhere(
      (attempt) => attempt.id == latestAttempt.id,
    );
    if (index != -1) {
      quizAttempts[index] = updatedAttempt;
    }

    return badgeId;
  }

  /// 获取用户答题统计
  Map<String, dynamic> getUserQuizStats(String userId) {
    final userAttempts = fetchUserQuizAttempts(userId);
    final monthlyAttempts = fetchUserMonthlyQuizAttempts(userId);

    int totalAttempts = userAttempts.length;
    int passedAttempts = userAttempts.where((attempt) => attempt.passed).length;
    int monthlyAttemptsCount = monthlyAttempts.length;
    bool canEarnBadge = canUserStartQuiz(userId);

    double averageScore =
        totalAttempts > 0
            ? userAttempts
                    .map((attempt) => attempt.correctCount)
                    .reduce((a, b) => a + b) /
                totalAttempts
            : 0.0;

    return {
      'totalAttempts': totalAttempts,
      'passedAttempts': passedAttempts,
      'monthlyAttempts': monthlyAttemptsCount,
      'canEarnBadge': canEarnBadge,
      'averageScore': averageScore,
      'successRate': totalAttempts > 0 ? (passedAttempts / totalAttempts) : 0.0,
    };
  }

  /// 获取题目总数
  int get questionCount => questions.length;

  /// 获取答题记录总数
  int get attemptCount => quizAttempts.length;

  /// 获取通过答题的用户数量
  int get passedUserCount {
    final passedUserIds =
        quizAttempts
            .where((attempt) => attempt.passed)
            .map((attempt) => attempt.userId)
            .toSet();
    return passedUserIds.length;
  }

  /// 获取本月获得徽章的用户数量
  int get monthlyBadgeEarnersCount {
    final now = DateTime.now();
    final startOfMonth = DateTime(now.year, now.month, 1);

    final badgeEarners =
        quizAttempts
            .where(
              (attempt) =>
                  attempt.awardedBadgeId != null &&
                  attempt.attemptDate.isAfter(startOfMonth),
            )
            .map((attempt) => attempt.userId)
            .toSet();

    return badgeEarners.length;
  }
}
